package com.example.mycalender;

import java.util.Calendar;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.MonthDisplayHelper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class MyCalenderView extends LinearLayout {
	private TableLayout tlayout;
	private MonthDisplayHelper monthDisplayHelper;
	private String[] weekDays = new String[] { "日", "一", "二", "三", "四", "五",
			"六" };
	private LinearLayout llWeeks;
	private Context context;
	private ItemClickListener clickListenner;
	private ViewFactory factory;

	private Calendar selectedDate;
	
	private View selectedView;

	public MyCalenderView(Context context) {
		this(context, null);
	}

	public MyCalenderView(Context context, AttributeSet attrs) {
		super(context, attrs);
		LayoutInflater.from(context).inflate(R.layout.mycalender, this);
		this.context = context;
		Calendar cal = Calendar.getInstance();
		selectedDate = cal;
		monthDisplayHelper = new MonthDisplayHelper(cal.get(Calendar.YEAR),
				cal.get(Calendar.MONTH));
		initCalender();
	}

	private void initCalender() {
		llWeeks = (LinearLayout) findViewById(R.id.tlWeeks);
		tlayout = (TableLayout) findViewById(R.id.calender);
		initWeekName();
		reflashCalendar();
	}

	/** 头部星期名称 */
	private void initWeekName() {
		for (int i = 0; i < 7; i++) {
			TextView tvWeek = new TextView(context);
			LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0,
					LayoutParams.WRAP_CONTENT);
			lp.weight = 1f;
			tvWeek.setLayoutParams(lp);
			tvWeek.setGravity(Gravity.CENTER);
			tvWeek.setText(weekDays[i]);
			llWeeks.addView(tvWeek);
		}
	}

	/** 刷新日历 */
	public void reflashCalendar() {
		tlayout.removeAllViews();

		int year = monthDisplayHelper.getYear();
		int month = monthDisplayHelper.getMonth() + 1; // java 月份是0开始
		int rowCount = monthDisplayHelper.getDayAt(5, 6) > 6 ? 5 : 6; // 最后一个的天数大于6说明最后一行是下个月的可以不显示
		for (int row = 0; row < rowCount; row++) {
			TableRow tr = new TableRow(context);
			int[] days = monthDisplayHelper.getDigitsForRow(row);
			for (int col = 0, len = days.length; col < len; col++) {
				int realMonth = month;
				int day = days[col];
				if (row == 0 && day > 7) {
					realMonth = month - 1;
				} else if (row > 3 && day < 14) {
					realMonth = month + 1;
				}
				int realYear = year;
				if (realMonth > 12) {
					realYear++;
					realMonth = 1;
				} else if (realMonth == 0) {
					realYear--;
					realMonth = 12;
				}
				final int finalYear = realYear;
				final int finalMonth = realMonth;
				final int finalDay = day;
				final boolean isInCurrentMonth = monthDisplayHelper
						.isWithinCurrentMonth(row, col);

				View cellView = null;
				if (null != factory) {
					cellView = factory.getCellView(context, finalYear,
							finalMonth, finalDay, isInCurrentMonth);
				}
				if (null == cellView) {
					cellView = getDefaultCellView(finalYear, finalMonth,
							finalDay, isInCurrentMonth);
				}
				cellView.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						if (null != clickListenner) {
							selectedDate = getCalender(finalYear,
									finalMonth - 1, finalDay);
							if(null!=selectedView){//取消以前选中
								selectedView.setSelected(false);
							}
							v.setSelected(true);
							selectedView=v;
							clickListenner.onItemClick(finalYear, finalMonth,
									finalDay, isInCurrentMonth);
						}
					}
				});
				if (selectedDate.get(Calendar.YEAR) == finalYear
						&& selectedDate.get(Calendar.MONTH) == finalMonth - 1
						&& selectedDate.get(Calendar.DATE) == finalDay) {
					cellView.performClick(); // 是选中View的自动点击,达到选中目的
				}
				tr.addView(cellView);
			}
			tlayout.addView(tr);
		}
	}

	/** 默认日历一个小格的View */
	public TextView getDefaultCellView(int year, int month, int day,
			boolean isCurrentMonth) {
		TextView tv = new TextView(context);
		TableRow.LayoutParams lp = new TableRow.LayoutParams(0, 80);
		lp.weight = 1f;
		tv.setLayoutParams(lp);
		tv.setText(day + "");
		tv.setGravity(Gravity.CENTER);

		if (!isCurrentMonth) {
			tv.setBackgroundColor(Color.GRAY);
		}
		tv.setFocusable(true);
		tv.setBackgroundResource(R.drawable.selecotr);
		return tv;
	}

	/** 取得月历当前年份 */
	public int getYear() {
		return monthDisplayHelper.getYear();
	}

	/** 取得月历当前月份 */
	public int getMonth() {
		return monthDisplayHelper.getMonth() + 1;
	}

	/** 设置头部星期名称,星期日为第一个,供7个 */
	public void setWeekDayNames(String[] weekDays) {
		this.weekDays = weekDays;
	}

	/** 上一个月 */
	public void pervMonth() {
		monthDisplayHelper.previousMonth();
		setSelectedDate();
		reflashCalendar();
	}

	/** 下一个月 */
	public void nextMonth() {
		monthDisplayHelper.nextMonth();
		setSelectedDate();
		reflashCalendar();
	}

	/** 设置选定日期,本月选择当日,否则选择1号 */
	private void setSelectedDate() {
		int year = monthDisplayHelper.getYear();
		int month = monthDisplayHelper.getMonth();
		selectedDate = Calendar.getInstance();
		if (!isCurrentMonth(year, month)) {
			selectedDate = getCalender(year, month, 1);
		}
	}

	private Calendar getCalender(int year, int month, int day) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month);
		cal.set(Calendar.DATE, day);
		return cal;
	}

	/** 跳至某个日期 */
	public void jumpTo(int year, int month) {
		monthDisplayHelper = new MonthDisplayHelper(year, month - 1);
		reflashCalendar();
	}

	/** 设置单元格监听器 */
	public void setOnItemClickListener(ItemClickListener listener) {
		this.clickListenner = listener;
	}

	/** 设置日历单元格View产生工厂 */
	public void setViewFactory(ViewFactory factory) {
		this.factory = factory;
	}

	/** 是否是当前月 */
	private boolean isCurrentMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		if (cal.get(Calendar.YEAR) == year && cal.get(Calendar.MONTH) == month) {
			return true;
		}
		return false;
	}

	/** 日历单元格点击监听器 */
	public interface ItemClickListener {
		/** 日历单元格点击监听器 */
		public void onItemClick(int year, int month, int day,
				boolean isInCurrentMonth);
	}

	/** 日历单元格View产生工厂 */
	public interface ViewFactory {
		/** 自定义日历单元格的View */
		public View getCellView(Context context, int year, int month, int day,
				boolean isInCurrentMonth);
	}
}
